package cemp.service;

import cemp.consts.WxUrlConst;
import cemp.util.MessageUtils;
import cemp.util.UrlUtils;
import cn.hutool.json.JSONUtil;

import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信平台 消息
 *
 *
 * @author lcb
 */
@Slf4j
@Service
public class WxMessageService {

    @Value("${notice.app.routine.appid}")
    private String appid;
    @Value("${notice.app.routine.secret}")
    private String secret;
    @Value("${notice.mini.program}")
    private String miniprogramState;

    @Autowired
    private RestTemplate restTemplate;

//    @Autowired
//    private RedisService redisService;


    public boolean wxSendMessage(String openId,String accessToken,String templateId,Map<String,Object> params){
        String url = WxUrlConst.URL_ROUTINE_SEND_MESSAGE.concat("?access_token="+accessToken) ;
        Map<String,Object> payload = new HashMap<>();
        payload.put("touser",openId);
        payload.put("template_id",templateId);
        payload.put("page","/pages/index/index");          //回调页面
        payload.put("miniprogram_state",miniprogramState);       //跳转小程序类型：developer为开发版；trial为体验版；formal为正式版；默认为正式版
        payload.put("data", MessageUtils.transMiniParam(params));
        String postJson = JSONUtil.toJsonStr(payload);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map> request = new HttpEntity<>(payload, headers);
        String responseJson = restTemplate.postForObject(url,request,String.class);
        System.out.println("show result: "+ responseJson);
        JSONObject response =  JSONObject.parseObject(responseJson);
        /**
         * 几个返回demo
         * {"errcode":47003,"errmsg":"argument invalid! data.character_string2.value i rid: 681d60cd-64d73fa3-1bbe1c02"}
         * {"errcode":0,"errmsg":"ok","msgid":3978947593895149581}
         * {"errcode":43101,"errmsg":"user refuse to accept the msg rid: 681d61d6-3f609cb5-493e07b0"}
         */
        if( response.getInteger("errcode")>0 ){
            return false;
        }
        return true;
    }

    public boolean miniSend(String openId, String templateId, Map<String, Object> params) {
        boolean sendSuceess;
        try {
            //拿accessToken
            String accessToken = this.wxGetAccessToken();
            sendSuceess = this.wxSendMessage(openId,accessToken,templateId,params);

        }catch (Exception e){
            sendSuceess = false;
        }
        return sendSuceess;
    }

    public String wxGetAccessToken(){
        Map<String, String> formParams = new HashMap<>();
        formParams.put("grant_type","client_credential");
        formParams.put("appid", appid);
        formParams.put("secret", secret);
        String url = UrlUtils.urlJoin(WxUrlConst.URL_ROUTINE_GET_ACCESS,formParams);
        String resp = restTemplate.getForObject(url,String.class);
        //token 维护 todo redis
        JSONObject jResp = JSONObject.parseObject(resp);
        return jResp.getString("access_token");
    }
//
//    /**
//     * 初始化商户JSApi支付Service配置
//     * @param req
//     * @return
//     */
//    public JsapiServiceExtension initWxPayService(WxConfigReq req) {
//        Config config =
//                new RSAAutoCertificateConfig.Builder()
//                        .merchantId(req.getMerchantId())
//                        // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥，商户私钥会用来生成请求的签名
//                        .privateKeyFromPath(req.getPrivateKeyPath())
//                        .merchantSerialNumber(req.getSerialNo())
//                        .apiV3Key(req.getApiV3Key())
//                        .build();
//        // 初始化服务
//        JsapiServiceExtension service =
//                new JsapiServiceExtension.Builder()
//                        .config(config)
//                        .signType("RSA") // 不填默认为RSA
//                        .build();
//        return service;
//    }
//
//
//    /**
//     * 初始化商户退款Service配置
//     * @param req
//     * @return
//     */
//    public RefundService initWxRefundService(WxConfigReq req) {
//        Config config =
//                new RSAAutoCertificateConfig.Builder()
//                        .merchantId(req.getMerchantId())
//                        // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥，商户私钥会用来生成请求的签名
//                        .privateKeyFromPath(req.getPrivateKeyPath())
//                        .merchantSerialNumber(req.getSerialNo())
//                        .apiV3Key(req.getApiV3Key())
//                        .build();
//        RefundService service =
//                new RefundService.Builder()
//                        .config(config)
//                        .build();
//        return service;
//    }
//
//    //////////////// JSAPI 付款 //////////////////
//
//    /**
//     * JSAPI支付下单，并返回JSAPI调起支付数据
//     */
//    public PrepayWithRequestPaymentResponse prepayWithRequestPayment(WxConfigReq req, PrepayRequest request) throws Exception {
//        return initWxPayService(req).prepayWithRequestPayment(request);
//    }
//
//    /**
//     * 关闭订单
//     */
//    public void closeOrder(WxConfigReq req, CloseOrderRequest request) {
//        // 调用request.setXxx(val)设置所需参数，具体参数可见Request定义
//        // 调用接口
//        initWxPayService(req).closeOrder(request);
//    }
//
//
//    /**
//     * 微信支付订单号查询订单
//     */
//    public Transaction queryOrderById(WxConfigReq req, QueryOrderByIdRequest request) {
//        // 调用request.setXxx(val)设置所需参数，具体参数可见Request定义
//        // 调用接口
//        return initWxPayService(req).queryOrderById(request);
//    }
//
//    /**
//     * 商户订单号查询订单
//     */
//    public Transaction queryOrderByOutTradeNo(WxConfigReq req, QueryOrderByOutTradeNoRequest request) {
//        // 调用request.setXxx(val)设置所需参数，具体参数可见Request定义
//        // 调用接口
//        return initWxPayService(req).queryOrderByOutTradeNo(request);
//    }
//
//    ////////////////////////////支付回调////////////////////////////
//
//    /**
//     * 微信支付回调返回结果
//     *
//     * @param request
//     * @return
//     */
//    public Transaction wxPayNotify(HttpServletRequest request, WxConfigReq req) {
//        //获取报文
//        String body = getRequestBody(request);
//        //随机串
//        String nonceStr = request.getHeader("Wechatpay-Nonce");
//        //微信传递过来的签名
//        String signature = request.getHeader("Wechatpay-Signature");
//        //证书序列号（微信平台）
//        String serialNo = request.getHeader("Wechatpay-Serial");
//        //时间戳
//        String timestamp = request.getHeader("Wechatpay-Timestamp");
//
//        log.info("wx notify body:{}", body);
//        // 构造 RequestParam
//        RequestParam requestParam = new RequestParam.Builder()
//                .serialNumber(serialNo)
//                .nonce(nonceStr)
//                .signature(signature)
//                .timestamp(timestamp)
//                .body(body)
//                .build();
//
//        // 如果已经初始化了 RSAAutoCertificateConfig，可直接使用
//        // 没有的话，则构造一个
//        NotificationConfig config = new RSAAutoCertificateConfig.Builder()
//                .merchantId(req.getMerchantId())
//                .privateKeyFromPath(req.getPrivateKeyPath())
//                .merchantSerialNumber(req.getSerialNo())
//                .apiV3Key(req.getApiV3Key())
//                .build();
//
//        // 初始化 NotificationParser
//        NotificationParser parser = new NotificationParser(config);
//
//        try {
//            // 以支付通知回调为例，验签、解密并转换成 Transaction
//            Transaction transaction = parser.parse(requestParam, Transaction.class);
//            return transaction;
//        } catch (ValidationException e) {
//            // 签名验证失败，返回 401 UNAUTHORIZED 状态码
//            log.error("签名验证失败 sign verification failed", e);
//        }
//        return null;
//    }
//
//
//    ////////////////////////////退款////////////////////////////
//
//    /**
//     * 退款申请
//     */
//    public Refund createRefundOrder(WxConfigReq req, CreateRequest request) {
//        // 调用request.setXxx(val)设置所需参数，具体参数可见Request定义
//        // 调用接口
//        return initWxRefundService(req).create(request);
//    }
//
//    /**
//     * 查询单笔退款（通过商户退款单号）
//     */
//    public Refund queryByOutRefundNo(WxConfigReq req, QueryByOutRefundNoRequest request) {
//        // 调用request.setXxx(val)设置所需参数，具体参数可见Request定义
//        // 调用接口
//        return initWxRefundService(req).queryByOutRefundNo(request);
//    }
//
//    ////////////////////////////支付回调////////////////////////////
//
//    /**
//     * 微信退款回调返回结果
//     *
//     * @param request
//     * @return
//     */
//    public RefundNotification wxRefundNotify(HttpServletRequest request, WxConfigReq req) {
//        //获取报文
//        String body = getRequestBody(request);
//        //随机串
//        String nonceStr = request.getHeader("Wechatpay-Nonce");
//        //微信传递过来的签名
//        String signature = request.getHeader("Wechatpay-Signature");
//        //证书序列号（微信平台）
//        String serialNo = request.getHeader("Wechatpay-Serial");
//        //时间戳
//        String timestamp = request.getHeader("Wechatpay-Timestamp");
//
//        log.info("wx notify body:{}", body);
//        // 构造 RequestParam
//        RequestParam requestParam = new RequestParam.Builder()
//                .serialNumber(serialNo)
//                .nonce(nonceStr)
//                .signature(signature)
//                .timestamp(timestamp)
//                .body(body)
//                .build();
//
//        // 如果已经初始化了 RSAAutoCertificateConfig，可直接使用
//        // 没有的话，则构造一个
//        NotificationConfig config = new RSAAutoCertificateConfig.Builder()
//                .merchantId(req.getMerchantId())
//                .privateKeyFromPath(req.getPrivateKeyPath())
//                .merchantSerialNumber(req.getSerialNo())
//                .apiV3Key(req.getApiV3Key())
//                .build();
//
//        // 初始化 NotificationParser
//        NotificationParser parser = new NotificationParser(config);
//
//        try {
//            // 以支付通知回调为例，验签、解密并转换成 Transaction
//            RefundNotification refundNotification = parser.parse(requestParam, RefundNotification.class);
//            return refundNotification;
//        } catch (ValidationException e) {
//            // 签名验证失败，返回 401 UNAUTHORIZED 状态码
//            log.error("签名验证失败 sign verification failed", e);
//        }
//        return null;
//    }
//
//
//    ///////////////////////////////////////////////////////////////////
//
//    /**
//     * 读取请求数据流
//     *
//     * @param request
//     * @return
//     */
//    public String getRequestBody(HttpServletRequest request) {
//        StringBuffer sb = new StringBuffer();
//        try (ServletInputStream inputStream = request.getInputStream();
//             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//        ) {
//            String line;
//            while ((line = reader.readLine()) != null) {
//                sb.append(line);
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return sb.toString();
//    }


}
